package com.psp.bu.service.impl;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.northend.util.MD5Util;
import com.northend.util.NumUtil;
import com.northend.util.RandomUtil;
import com.northend.util.StringUtil;
import com.northend.util.VCodeSender;
import com.psp.bu.cache.dao.UserCacheDao;
import com.psp.bu.constants.StringConstants;
import com.psp.bu.model.Code;
import com.psp.bu.model.UserBean;
import com.psp.bu.model.UserLoginLogBean;
import com.psp.bu.model.UserUpdateLogBean;
import com.psp.bu.netease.NeteaseManager;
import com.psp.bu.persist.dao.UserDao;
import com.psp.bu.service.UserService;
import com.psp.bu.service.exception.ServiceException;

@Service
public class UserServiceImpl implements UserService {
	Logger logger = Logger.getLogger(UserServiceImpl.class);
	@Autowired
	UserDao userImpl;
	@Autowired
	UserCacheDao userCacheImpl;

	@Autowired
	NeteaseManager neteaseManager;

	VCodeSender phoneCode = VCodeSender.getInstance("N1330628", "t7NYh90uB");

	@Transactional(rollbackFor = Exception.class)
	@Override
	public UserBean login(String sessionId, String userName, String pwd, String vcode, String device, String ip) {
		Code code = userCacheImpl.getLoginCode(userName);
		if (code == null) {
			code = new Code();
			code.setNum(0);
			userCacheImpl.setLoginCode(userName, code);
		} else if (code.getNum() > 4) {
			if (StringUtil.isEmpty(code.getCode())) {
				throw new ServiceException("imgcode_is_cross");
			}
			if (StringUtil.isEmpty(vcode) || !code.getCode().equals(vcode.toUpperCase())) {
				throw new ServiceException("imgcode_is_error");
			}
		}
		UserBean user = null;
		if (StringUtil.isMobileNO(userName)) {
			user = userImpl.selectOneByPhone(userName);
		}
		if (user == null) {
			code.setNum(code.getNum() + 1);
			userCacheImpl.setLoginCode(userName, code);
			throw new ServiceException("object_is_not_exist", new Object[] { "用户" });
		}

		pwd = MD5Util.sha256Hex(pwd);
		if (!pwd.equals(user.getPassword())) {
			code.setNum(code.getNum() + 1);
			userCacheImpl.setLoginCode(userName, code);
			throw new ServiceException("user_password_is_error");
		}

		if (NumUtil.toInt(user.getState(), 0) == 2) {
			throw new ServiceException("user_is_not_active");
		}

		userCacheImpl.setUserSession(sessionId, user.getBuid(), 86400L);
		boolean flag = userImpl.updateLoginTime(user.getBuid()) > 0;
		if (flag) {
			neteaseManager.update(user.getBuid(), null, sessionId); // TODO 更新网易云信账户

			UserLoginLogBean loginLog = new UserLoginLogBean();
			loginLog.setDevice(device);
			loginLog.setLoginIp(ip);
			loginLog.setUid(user.getBuid());
			loginLog.setOstate(1);// 1 登录 2注册
			flag = userImpl.insertLoginLog(loginLog) > 0;
			if (!flag) {
				throw new ServiceException("fail");
			}
			code = new Code();
			code.setNum(0);
			userCacheImpl.setLoginCode(userName, code);
		}

		return user;
	}

	@Override
	public UserBean existUser(int type, String username) {
		UserBean user = null;
		if (StringUtil.isMobileNO(username)) {
			user = userImpl.selectOneByPhone(username);
		}
		if (type == 1) {
			if (user == null) {
				throw new ServiceException("object_is_not_exist", new Object[] { "用户" });
			}
		} else if ((type == 2) && (user != null)) {
			throw new ServiceException("object_is_exist", new Object[] { "用户" });
		}
		return user;
	}

	@Override
	public UserBean existUser(String sessionId) {
		String uid = userCacheImpl.getUidBySession(sessionId);
		if (uid == null) {
			return null;
		}
		return userImpl.selectOne(uid);
	}

	@Override
	public UserBean getUser(String userId) {
		if(userId == null) {
			userId = "serviceCategory1";
		}
		return userImpl.selectOne(userId);
	}

	@Override
	public UserBean sendFindPwdCode(String userName, String code, String key) {
		UserBean user = userImpl.selectOneByPhone(userName);
		if (user == null)
			throw new ServiceException("object_is_not_exist", new Object[] { "未注册，手机号" });
		checkImgCode(key, code);
		String vcode = RandomUtil.getRandomNum(4);
		logger.info("the phone vcode is : " + vcode);
		Code cacheCode = new Code();
		cacheCode.setCode(vcode);
		cacheCode.setTime(System.currentTimeMillis() / 1000);

		// userCacheImpl.setVCode(3, userName, cacheCode);
		boolean flag = false;
		if (StringUtil.isMobileNO(userName)) {// 手机发送短信验证码
			String msg = StringConstants.getInstance().getString("msg_vcode_send", new Object[] { vcode, 5 });
			flag = phoneCode.send(userName, msg, null);
		}
		if (flag) {
			userCacheImpl.setVCode(3, userName, cacheCode);
		}
		Code c = userCacheImpl.getVCode(3, userName);
		logger.info("vcode is : " + c);

		return user;
	}

	public void checkImgCode(String userName, String i) {
		Code imgCode = userCacheImpl.getImgCode(userName);
		logger.info("the imgcode is : " + imgCode);
		if (imgCode == null) {
			throw new ServiceException("imgcode_is_expire");
		}
		i = i.toUpperCase();
		if ((StringUtil.isEmpty(i)) || (!i.equals(imgCode.getCode()))) {
			logger.info("set imgcode is : " + imgCode);
			throw new ServiceException("imgcode_is_error");
		}
	}

	@Override
	public UserBean confirmFindPwdCode(String account, String vcode) {
		Code code = userCacheImpl.getVCode(3, account);// 1 绑定手机号，2 更新手机号,3 找回密码
		if (code == null) {
			throw new ServiceException("vcode_is_expire");
		}
		logger.info("account is:" + account + ", vcode is:" + vcode + ", code = " + code);
		if (!vcode.equals(code.getCode())) {
			throw new ServiceException("vcode_is_error");
		}
		UserBean user = new UserBean();
		if (StringUtil.isMobileNO(account)) {// 手机发送短信验证码
			user.setPhone(account);
		} else if (StringUtil.isEmail(account)) {
			user.setEmail(account);
		}
		return user;
	}

	@Override
	public boolean resetPwd(String phone, String vcode, String pwd, String confirmPwd) {

		Code code = userCacheImpl.getVCode(3, phone);// 1 绑定手机号，2 更新手机号,3 找回密码
		if (code == null) {
			throw new ServiceException("vcode_is_expire");
		}
		logger.info("account is:" + phone + ", vcode is:" + vcode + ", code = " + code);
		if (!vcode.equals(code.getCode())) {
			throw new ServiceException("vcode_is_error");
		}

		UserBean user = null;
		if (StringUtil.isMobileNO(phone)) {// 手机
			user = userImpl.selectOneByPhone(phone);
		}
		if (user == null) {
			throw new ServiceException("object_is_not_exist", new Object[] { "用户" });
		}
		String oldpwd = user.getPassword();
		if (!pwd.equals(confirmPwd)) {
			throw new ServiceException("user_password_is_not_same");
		}
		user.setPassword(MD5Util.sha256Hex(pwd));

		boolean flag = userImpl.updatePwd(user) > 0;
		if (flag) {
			UserUpdateLogBean updateLog = new UserUpdateLogBean();
			updateLog.setUid(user.getBuid());
			updateLog.setOldData("密码：" + oldpwd);
			updateLog.setOstate(1);
			flag = userImpl.insertUpdateLog(updateLog) > 0;
			if (!flag) {
				throw new ServiceException("fail");
			}
		}
		return flag;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public UserBean updateUser(String userId, String content, int type) {
		UserBean user = userImpl.selectOne(userId);
		if (user == null) {
			throw new ServiceException("object_is_not_exist", new Object[] { "用户" });
		}
		String oldData = null;
		// 1姓名2头像，3身份证，4性别
		switch (type) {
		case 1:
			oldData = "昵称：" + user.getNickName();
			user.setNickName(content);
			break;
		case 2:
			oldData = "头像：" + user.getHeadIcon();
			user.setHeadIcon(content);
			break;
		case 3:
			oldData = "身份证：" + user.getIdNo();
			user.setIdNo(content);
			break;
		case 4:
			oldData = "性别：" + user.getGender();
			user.setGender(NumUtil.toInt(content, 1));// 默认设置男
			break;
		default:
			break;
		}
		boolean flag = userImpl.updateUser(user) > 0;
		if (flag) {
			UserUpdateLogBean updateLog = new UserUpdateLogBean();
			updateLog.setUid(userId);
			updateLog.setOldData(oldData);
			updateLog.setData(content);
			updateLog.setOstate(1);
			flag = userImpl.insertUpdateLog(updateLog) > 0;
			if (!flag) {
				throw new ServiceException("fail");
			}
		}
		return user;
	}

	@Override
	public boolean checkUserPhone(String phone, String vcode) {
		Code code = userCacheImpl.getVCode(2, phone);// 根据类型获取更新手机号是验证码
		if (code == null) {
			throw new ServiceException("vcode_is_expire");
		}

		logger.info("phone is:" + phone + ", vcode is:" + vcode + ", code = " + code);
		if (!vcode.equals(code.getCode())) {
			throw new ServiceException("vcode_is_error");
		}
		return true;
	}

	@Override
	public boolean resetPassword(String userId, String oldPwd, String password, String confirmPwd) {
		// 更新用户密码
		UserBean user = userImpl.selectOne(userId);
		if (user == null) {
			throw new ServiceException("object_is_not_exist", new Object[] { "用户" });
		}
		String old = MD5Util.sha256Hex(oldPwd);
		if (!old.equals(user.getPassword())) {
			throw new ServiceException("param_is_error", "输入密码");
		}

		if (!password.equals(confirmPwd)) {
			throw new ServiceException("user_password_is_not_same");
		}

		if (password.equals(oldPwd)) {
			throw new ServiceException("user_password_can_not_same");
		}

		user.setPassword(MD5Util.sha256Hex(password));
		boolean flag = userImpl.updatePwd(user) > 0;
		if (flag) {
			UserUpdateLogBean updateLog = new UserUpdateLogBean();
			updateLog.setUid(user.getBuid());
			updateLog.setOldData("密码：" + old);
			updateLog.setOstate(1);
			flag = userImpl.insertUpdateLog(updateLog) > 0;
			if (!flag) {
				throw new ServiceException("fail");
			}
		}
		return flag;
	}
}
